/**
 * 全局axios请求配置
 * 
 * @author 邓志军
 * @since 2024年1月20日08:47:31
 */
import axios from 'axios'
import storage from '@/store';
import { getToken } from "@/utils/auth.js"
import { MessageBox } from 'element-ui'
import message from "@/plugins/modal.js"

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项，表示请求URL公共部分
  // 注意！！ 这里是全局统一加上了 '/项目名称' 前缀，也就是说所有接口都会加上'/api'前缀
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 500000
})

// 验证是否为blob格式
function blobValidate(data) {
  return data.type !== 'application/json'
}

/**
 * 请求拦截器
 * 
 * 作用：可以拦截请求发送，对这次请求发送之前做一些事情
 * 举例：可以统一添加token，对请求参数进行加密
 */
service.interceptors.request.use(
  (config) => {
    // 是否需要防止数据重复提交
    const isRepeatSubmit = (config.headers || {}).repeatSubmit === false

    // 设置默认请求头为json格式
    if (['get', 'put', 'delete'].includes(config.method) && config.params) {
      // 对查询参数进行 URL 编码
      const encodedParams = new URLSearchParams(config.params);
      // 将编码后的查询参数赋值给原先的params
      config.params = encodedParams;
    }

    const token = getToken();

    config.headers['Authorization'] = "Bearer " + token;  // 设置请求头

    if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
      const requestObj = {
        url: config.url,
        data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
        time: new Date().getTime()
      }
      const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
      const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
      if (requestSize >= limitSize) {
        console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制，无法进行防重复提交验证。')
      }
    }
    return config;
  },
  (error) => {
    return Promise.error(error);
  }
);

// 添加响应拦截器
// 可以在接口响应后统一处理结果
// 2xx 范围内的状态码都会触发该函数。
service.interceptors.response.use(function (response) {
  let res = response.data;
  // 不是json 并且是 blob
  if (!["application/json", "application/json;charset=utf-8"].includes(response.headers["content-type"]) && blobValidate(response)) {
    return response
  }
  if (+res.code == 401) {
    return MessageBox.confirm('会话状态已过期，您可以继续留在该页面，或重新登录', '系统提示', {
      confirmButtonText: '重新登陆',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(() => {
      storage.dispatch('Logout').then(() => location.href = '/index')
    })
  }
  return res;
}, function (error) {
  console.log("err = ", error);
  // 超出 2xx 范围的状态码都会触发该函数。
  if (error.response.status == 500) {
    return message.msgError("服务器更新维中,请稍后尝试...")
  }
  // 对响应错误做点什么
  return Promise.reject(error);
});

export default service;